package com.ai.bitcoin.controller;

import com.ai.bitcoin.bo.*;
import com.ai.bitcoin.common.resp.ResponseEntity;
import com.ai.bitcoin.enums.MonitorSettingEnum;
import com.ai.bitcoin.enums.ResponseEnum;
import com.ai.bitcoin.exception.BusinessException;
import com.ai.bitcoin.jpa.dao.BccId2MarketDao;
import com.ai.bitcoin.jpa.dao.BccReportMonitorConfigDao;
import com.ai.bitcoin.jpa.dao.ExchangeUserRelDao;
import com.ai.bitcoin.jpa.entity.BccId2Market;
import com.ai.bitcoin.jpa.entity.BccReportMonitorConfig;
import com.ai.bitcoin.jpa.entity.ExchangeUserRel;
import com.ai.bitcoin.jpa.service.BccReportMonitorConfigService;
import com.ai.bitcoin.jpa.service.ExchangeUserService;
import com.ai.bitcoin.service.helper.PushTemplateEsBizHelper;
import com.ai.bitcoin.service.helper.RandomHelper;
import com.ai.bitcoin.vo.ExchangFindByBccIdVO;
import com.ai.bitcoin.vo.ExchangeMonitorSettingVO;
import com.ai.bitcoin.vo.UpdatePriceDetailVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.async.DeferredResult;

import javax.validation.Valid;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CompletableFuture;

/**
 * @description: 交易所
 * @author: gulj
 * @create: 2018-08-02 21:28
 **/
@RestController
@RequestMapping("/exchange")
@Slf4j
public class ExchangeController {

    @Autowired
    private ExchangeUserService exchangeUserService;

    @Autowired
    private BccId2MarketDao bccId2MarketDao;

    @Autowired
    private ExchangeUserRelDao exchangeUserRelDao;

    @Autowired
    private BccReportMonitorConfigDao monitorConfigDao;

    @Autowired
    private PushTemplateEsBizHelper pushTemplateEsBizHelper;

    @Autowired
    private BccReportMonitorConfigService bccReportMonitorConfigService;

    /**
     * 根据bccId查询对应的交易所信息
     *
     * @param findByBccIdBO
     * @return
     */
    @PostMapping("/findByBccId")
    public ResponseEntity<ExchangFindByBccIdVO> findByBccId(@RequestBody @Valid ExchangeFindByBccIdBO findByBccIdBO) {
        ExchangFindByBccIdVO exchangFindByBccIdVO = new ExchangFindByBccIdVO();
        List<BccId2Market> bccId2Markets = bccId2MarketDao.findByBccIdAndDelFlag(findByBccIdBO.getBccId(), "0");
        exchangFindByBccIdVO.setBccId2Markets(bccId2Markets);
        List<ExchangeUserRel> exchangeUserRels = exchangeUserRelDao.findByOpenId(findByBccIdBO.getOpenId());
        if (null != exchangeUserRels && !exchangeUserRels.isEmpty()) {
            String exchangeName = exchangeUserRels.get(0).getExchangeName();
            if (StringUtils.isEmpty(exchangeName)) {
                exchangFindByBccIdVO.setExchangeNames(new String[]{});
            }
            else {
                exchangFindByBccIdVO.setExchangeNames(exchangeName.split(","));
            }
        }
        return new ResponseEntity(ResponseEnum.SUCCESS, exchangFindByBccIdVO);
    }

    /**
     * 更新和保存用户配置的交易所
     *
     * @param exchangeUserRel
     * @return
     */
    @PostMapping("/saveOrUpdateConfigExchange")
    public ResponseEntity saveOrUpdateConfigExchange(@RequestBody ExchangeUserRel exchangeUserRel) {
        if (StringUtils.isEmpty(exchangeUserRel.getId())) {
            exchangeUserRel.setCreateTime(new Date());
        }
        exchangeUserRel.setUpdateTime(new Date());
        List<ExchangeUserRel> exchangeUserRelList = exchangeUserRelDao.findByOpenId(exchangeUserRel.getOpenId());
        if (exchangeUserRelList == null || exchangeUserRelList.isEmpty()) {
            ExchangeUserRel exchangeUserRel1 = exchangeUserRelDao.saveAndFlush(exchangeUserRel);
            return new ResponseEntity(ResponseEnum.SUCCESS, exchangeUserRel1);
        }
        else {
            exchangeUserRelDao.updateExchangeNameByOpenId(exchangeUserRel.getExchangeName(), exchangeUserRel.getOpenId());
            return new ResponseEntity(ResponseEnum.SUCCESS, null);
        }
    }


    /**
     * 监控页面设置
     *
     * @param monitorSettingBO
     * @return
     */
    @PostMapping("/monitorSetting")
    public ResponseEntity<ExchangeMonitorSettingVO> monitorSetting(@RequestBody @Valid ExchangeMonitorSettingBO monitorSettingBO) {
        // 检查用户是否配置过关注的交易所
        boolean isConfigExchange = exchangeUserService.checkUserConfigExchange(monitorSettingBO.getOpenId());
        if (!isConfigExchange) {
            return new ResponseEntity(MonitorSettingEnum.NOT_CONFIG_EXCHANGE.getCode(), MonitorSettingEnum.NOT_CONFIG_EXCHANGE.getMessage(), null);
        }

        // 监控配置
        BccReportMonitorConfig monitorConfig = monitorConfigDao.findByBccIdAndOpenId(monitorSettingBO.getBccId(), monitorSettingBO.getOpenId());
        if (monitorConfig == null) {
            // 未进行监控页面的任何设置，给用户初始化配置
            BccReportMonitorConfig build = new BccReportMonitorConfig();
            build.setBccId(monitorSettingBO.getBccId());
            build.setOpenId(monitorSettingBO.getOpenId());
            build.setBccNameEn(monitorSettingBO.getBccNameEn());
            build.setBoomBustSwitch(0);
            build.setNewsDynamicSwitch(0);
            build.setBuyerSellerPointSwitch(0);
            build.setErcTwoZeroSwitch(0);
            build.setReportSubscribeSwitch(0);
            build.setExchangeAnnoSwitch(0);
            build.setCreateTime(new Date());
            build.setUpdateTime(new Date());
            build.setCoinPriceRate(1);
            monitorConfigDao.save(build);
            ExchangeMonitorSettingVO monitorSettingVO = new ExchangeMonitorSettingVO();
            try {
                BeanUtils.copyProperties(build, monitorSettingVO);
            } catch (Exception e) {
                log.error("监控页面，拷贝属性异常 : {}", e);
                return new ResponseEntity<>(ResponseEnum.FAIL);
            }
            return new ResponseEntity(ResponseEnum.SUCCESS, monitorSettingVO);
        }

        ExchangeMonitorSettingVO monitorSettingVO = new ExchangeMonitorSettingVO();
        try {
            BeanUtils.copyProperties(monitorConfig, monitorSettingVO);
        } catch (Exception e) {
            log.error("监控页面，拷贝属性异常 : {}", e);
            return new ResponseEntity<>(ResponseEnum.FAIL);
        }
        // 查询使用人数
        List<Object[]> objects = monitorConfigDao.queryMonitorUserCountByBccId(monitorSettingBO.getBccId());
        if (objects != null && !objects.isEmpty()) {
            Integer ercTwoZeroSwitchCount = RandomHelper.getRandomInt(Integer.valueOf(objects.get(0)[0].toString()));
            Integer boomBustSwitchCount = RandomHelper.getRandomInt(Integer.valueOf(objects.get(0)[1].toString()));
            Integer exchangeAnnoSwitchCount = RandomHelper.getRandomInt(Integer.valueOf(objects.get(0)[2].toString()));
            Integer coinPriceRemindCount = RandomHelper.getRandomInt(Integer.valueOf(objects.get(0)[3].toString()));
            monitorSettingVO.setErcTwoZeroSwitchCount(ercTwoZeroSwitchCount);
            monitorSettingVO.setBoomBustSwitchCount(boomBustSwitchCount);
            monitorSettingVO.setExchangeAnnoSwitchCount(exchangeAnnoSwitchCount);
            monitorSettingVO.setCoinPriceRemindCount(coinPriceRemindCount);
        }
        return new ResponseEntity(ResponseEnum.SUCCESS, monitorSettingVO);
    }

    /**
     * 更新监控配置
     *
     * @param bccReportMonitorConfig
     * @return
     */
    @PostMapping("/updateMonitorSetting")
    public ResponseEntity updateMonitorSetting(@RequestBody BccReportMonitorConfig bccReportMonitorConfig) {
        BccReportMonitorConfig reportMonitorConfig = monitorConfigDao.findByBccIdAndOpenId(bccReportMonitorConfig.getBccId(), bccReportMonitorConfig.getOpenId());
        if (reportMonitorConfig == null) {
            log.info("【没有查询到可配置项,bccId:{},openId:{}】", bccReportMonitorConfig.getBccId(), bccReportMonitorConfig.getOpenId());
            return new ResponseEntity(-1, "没有查询到可配置项");
        }

        if (bccReportMonitorConfig.getReportSubscribeSwitch() != null) {
            reportMonitorConfig.setReportSubscribeSwitch(bccReportMonitorConfig.getReportSubscribeSwitch());
        }

        if (bccReportMonitorConfig.getExchangeAnnoSwitch() != null) {
            reportMonitorConfig.setExchangeAnnoSwitch(bccReportMonitorConfig.getExchangeAnnoSwitch());
        }

        if (bccReportMonitorConfig.getErcTwoZeroSwitch() != null) {
            reportMonitorConfig.setErcTwoZeroSwitch(bccReportMonitorConfig.getErcTwoZeroSwitch());
        }

        if (bccReportMonitorConfig.getBuyerSellerPointSwitch() != null) {
            reportMonitorConfig.setBuyerSellerPointSwitch(bccReportMonitorConfig.getBuyerSellerPointSwitch());
        }

        if (bccReportMonitorConfig.getNewsDynamicSwitch() != null) {
            reportMonitorConfig.setNewsDynamicSwitch(bccReportMonitorConfig.getNewsDynamicSwitch());
        }

        if (bccReportMonitorConfig.getBoomBustSwitch() != null) {
            reportMonitorConfig.setBoomBustSwitch(bccReportMonitorConfig.getBoomBustSwitch());
        }

        reportMonitorConfig.setUpdateTime(new Date());
        log.info("【更新过后的监控配置：{}】", reportMonitorConfig);
        monitorConfigDao.saveAndFlush(reportMonitorConfig);
        return new ResponseEntity(ResponseEnum.SUCCESS, null);
    }


    /**
     * 监控批量配置
     *
     * @param openId openId
     * @return http Result
     */
    @PostMapping("/getMonitorBatchSetting/{openId}")
    @Transactional
    @SuppressWarnings("unchecked")
    public DeferredResult<ResponseEntity<BatchMonitorSettingResultBO>> getMonitorBatchSetting(@PathVariable String openId) {
        DeferredResult<ResponseEntity<BatchMonitorSettingResultBO>> deferredResult = new DeferredResult<>(20 * 1000L);
        CompletableFuture.supplyAsync(() -> {
            try {
                //批量设置
                BatchMonitorSettingResultBO setting = bccReportMonitorConfigService.getMonitorBatchSetting(openId);
                return new ResponseEntity(200, "取得用户订阅配置。", setting);
            } catch (BusinessException e) {
                //返回错误信息
                return new ResponseEntity(-1, e.getMessage(), null);
            }
        }).whenCompleteAsync((result, throwable) -> deferredResult.setResult(result));

        return deferredResult;
    }

    /**
     * 监控批量配置
     *
     * @param settingBO 设置
     * @return http Result
     */
    @PostMapping("/monitorBatchSetting")
    @Transactional
    public DeferredResult<ResponseEntity<Object>> monitorBatchSetting(@RequestBody BatchMonitorSettingBO settingBO) {
        DeferredResult<ResponseEntity<Object>> deferredResult = new DeferredResult<>();
        CompletableFuture.supplyAsync(() -> {
            try {
                //批量设置
                bccReportMonitorConfigService.batchSetting(settingBO);
                return new ResponseEntity(200, "批量设置完成。", null);
            } catch (Exception e) {
                //返回错误信息
                return new ResponseEntity(-1, e.getMessage(), null);
            }
        }).whenCompleteAsync((result, throwable) -> deferredResult.setResult(result));

        return deferredResult;
    }


    /**
     * 价格详情
     *
     * @param monitorConfig
     * @return
     */
    @PostMapping("/priceDetail")
    public ResponseEntity<UpdatePriceDetailVO> priceDetail(@RequestBody BccReportMonitorConfig monitorConfig) {
        BccReportMonitorConfig reportMonitorConfig = monitorConfigDao.findByBccIdAndOpenId(monitorConfig.getBccId(), monitorConfig.getOpenId());
        if (reportMonitorConfig == null) {
            log.info("【没有查询到可配置项,bccId:{},openId:{}】", monitorConfig.getBccId(), monitorConfig.getOpenId());
            return new ResponseEntity(ResponseEnum.SUCCESS, null);
        }

        UpdatePriceDetailVO updatePriceDetailVO = new UpdatePriceDetailVO();
        BeanUtils.copyProperties(reportMonitorConfig, updatePriceDetailVO);

        // TODO 获取价格
        String latestPrice = pushTemplateEsBizHelper.getLatestPriceByBccIdAndMarket(monitorConfig.getBccId(), monitorConfig.getCoinPriceMarket());
        log.info("从es中获取到的最新价格为：{}", latestPrice);
        if (StringUtils.isEmpty(latestPrice)) {
            latestPrice = "";
        }
        updatePriceDetailVO.setLatestCoinPrice(latestPrice);
        // 交易所信息
        List<ExchangeUserRel> exchangeUserRels = exchangeUserRelDao.findByOpenId(monitorConfig.getOpenId());
        if (null != exchangeUserRels && !exchangeUserRels.isEmpty()) {
            String exchangeName = exchangeUserRels.get(0).getExchangeName();
            if (StringUtils.isNotEmpty(exchangeName)) {
                String[] exchangeNames = exchangeName.split(",");
                updatePriceDetailVO.setExchangeNames(exchangeNames);
            }
            else {
                updatePriceDetailVO.setExchangeNames(new String[]{});
            }
        }

        return new ResponseEntity(ResponseEnum.SUCCESS, updatePriceDetailVO);
    }


    /**
     * 保存价格详情
     *
     * @param savePriceDetailBO
     * @return
     */
    @PostMapping("/savePriceDetail")
    public ResponseEntity savePriceDetail(@RequestBody BccSavePriceDetailBO savePriceDetailBO) {
        String exchangeNames = savePriceDetailBO.getExchangeName();
        if (StringUtils.isEmpty(exchangeNames)) {
            return new ResponseEntity(MonitorSettingEnum.EXCHANGE_NAME_IS_EMPTY.getCode(), MonitorSettingEnum.EXCHANGE_NAME_IS_EMPTY.getMessage(), null);
        }

        // 更新交易所
        exchangeUserRelDao.updateExchangeNameByOpenId(exchangeNames, savePriceDetailBO.getOpenId());

        savePriceDetailBO.setCoinPriceMarket(exchangeNames);
        // 更新监控设置
        monitorConfigDao.updatePriceAndRate(savePriceDetailBO.getCoinPriceMin(), savePriceDetailBO.getCoinPriceMax(), savePriceDetailBO.getCoinPriceRate(), savePriceDetailBO.getCoinPriceMarket(), savePriceDetailBO.getId());

        return new ResponseEntity(ResponseEnum.SUCCESS);
    }


}
